/*
 * Copyright (C) 2012 Santiago Valdarrama
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.yuanmei.stockeyes.model;

import java.io.File;
import java.text.DecimalFormat;
import java.util.Calendar;

import com.yuanmei.stockeyes.artifacts.Constants;
import com.yuanmei.stockeyes.artifacts.Extensions;

public class Stock {

    private final String code;
    private int market_id;
    private String m_code;
    private String name;
    private Float changePercentage;
    private Float change;
    private Float price;
    private Float open;
    private Float Low;
    private Float High;
    private Float yesterdayClose;
    private Float volume;
    private Float turnover; //

    private Float bid5;
    private Float bidvol5;
    private Float bid4;
    private Float bidvol4;
    private Float bid3;
    private Float bidvol3;
    private Float bid2;
    private Float bidvol2;
    private Float bid1;
    private Float bidvol1;

    private Float ask1;
    private Float askvol1;
    private Float ask2;
    private Float askvol2;
    private Float ask3;
    private Float askvol3;
    private Float ask4;
    private Float askvol4;
    private Float ask5;
    private Float askvol5;

    private String lastTradeDate;

    private static String sKlineBaseDirectory = null;
    private static String sDayKlineDir = null;
    private static String sWeekKlineDir = null;
    private static String sMonthKlineDir = null;

    public long lastNotifyTime;

    public class TimeSeqData {
        public long mTime;
        public Float mPrice;
        public Float mVol;
        public Float mTurnover;

        public TimeSeqData(long time, Float price, Float vol, Float turnover) {
            mTime = time;
            mPrice = price;
            mVol = vol;
            mTurnover = turnover;
        }
    }

    public TimeSeqData CreateTimeSeqData(long time, Float price, Float vol,
            Float turnover) {
        return new TimeSeqData(time, price, vol, turnover);
    }

    public class StockPrices {
        public Float mHigh;
        public Float mLow;

        public StockPrices(Float High, Float Low) {
            mHigh = High;
            mLow = Low;
        }
    }

    private TimeSeqData[] mTsArray = null;

    public void updateTsArrays(TimeSeqData[] newArray) {
        mTsArray = newArray;
    }

    public StockPrices getPricesOfLastNDays(int NDays) {
        if (null == mTsArray)
            return null;

        long MinTime = getLastNDayOpenTime(NDays);
        long MaxTime = getLastNDayCloseTime(1);
        StockPrices result = new StockPrices(mTsArray[0].mPrice,
                mTsArray[0].mPrice);

        for (TimeSeqData ts : mTsArray) {
            if ((ts.mTime < MinTime) || (ts.mTime > MaxTime))
                continue;

            if (ts.mPrice > result.mHigh)
                result.mHigh = ts.mPrice;

            if (ts.mPrice < result.mLow)
                result.mLow = ts.mPrice;
        }
        return result;
    }

    public static void initKlineBaseDir(String ctxFilesDir) {
        if (ctxFilesDir == null)
            return;
        if (sKlineBaseDirectory != null)
            return;
        // sKlineBaseDirectory = context.getFilesDir().getAbsolutePath() +
        // "/kchart";
        sKlineBaseDirectory = ctxFilesDir + "/kchart";
        File file = new File(sKlineBaseDirectory);
        if (!file.exists()) {
            file.mkdir();
        }

        sDayKlineDir = sKlineBaseDirectory + "/day";
        file = new File(sDayKlineDir);
        if (!file.exists()) {
            file.mkdir();
        }

        sWeekKlineDir = sKlineBaseDirectory + "/week";
        file = new File(sWeekKlineDir);
        if (!file.exists()) {
            file.mkdir();
        }

        sMonthKlineDir = sKlineBaseDirectory + "/month";
        file = new File(sMonthKlineDir);
        if (!file.exists()) {
            file.mkdir();
        }
    }

    public Stock(String code, String name, Float changePercentage,
            Float change, Float price, Float open, Float Low, Float High,
            Float yesterdayClose, Float volume, Float turnover, Float bid5,
            Float bidvol5, Float bid4, Float bidvol4, Float bid3,
            Float bidvol3, Float bid2, Float bidvol2, Float bid1,
            Float bidvol1, Float ask1, Float askvol1, Float ask2,
            Float askvol2, Float ask3, Float askvol3, Float ask4,
            Float askvol4, Float ask5, Float askvol5, String update) {
        this.code = code;
        // this.market = market;
        this.name = name;
        this.changePercentage = changePercentage;
        this.change = change;
        this.price = price;
        this.open = open;
        this.Low = Low;
        this.High = High;
        this.yesterdayClose = yesterdayClose;
        setVolume(volume);
        this.turnover = turnover;

        this.bid5 = bid5;
        this.bidvol5 = bidvol5;
        this.bid4 = bid4;
        this.bidvol4 = bidvol4;
        this.bid3 = bid3;
        this.bidvol3 = bidvol3;
        this.bid2 = bid2;
        this.bidvol2 = bidvol2;
        this.bid1 = bid1;
        this.bidvol1 = bidvol1;
        this.ask1 = ask1;
        this.askvol1 = askvol1;
        this.ask2 = ask2;
        this.askvol2 = askvol2;
        this.ask3 = ask3;
        this.askvol3 = askvol3;
        this.ask4 = ask4;
        this.askvol4 = askvol4;
        this.ask5 = ask5;
        this.askvol5 = askvol5;

        this.lastTradeDate = update;
    }

    public Stock(String code, String name, int market_id, String m_code) {
        this.code = code;
        this.name = name;
        this.market_id = market_id;
        this.m_code = m_code;
    }

    public void update(Float changePercentage, Float change, Float price,
            Float open, Float Low, Float High, Float yesterdayClose, Float volume,
            Float turnover, Float bid5, Float bidvol5, Float bid4,
            Float bidvol4, Float bid3, Float bidvol3, Float bid2,
            Float bidvol2, Float bid1, Float bidvol1, Float ask1,
            Float askvol1, Float ask2, Float askvol2, Float ask3,
            Float askvol3, Float ask4, Float askvol4, Float ask5,
            Float askvol5, String update) {

        this.changePercentage = changePercentage;
        this.change = change;
        this.price = price;
        this.open = open;
        this.Low = Low;
        this.High = High;
        this.yesterdayClose = yesterdayClose;
        setVolume(volume);
        this.turnover = turnover;

        this.bid5 = bid5;
        this.bidvol5 = bidvol5;
        this.bid4 = bid4;
        this.bidvol4 = bidvol4;
        this.bid3 = bid3;
        this.bidvol3 = bidvol3;
        this.bid2 = bid2;
        this.bidvol2 = bidvol2;
        this.bid1 = bid1;
        this.bidvol1 = bidvol1;
        this.ask1 = ask1;
        this.askvol1 = askvol1;
        this.ask2 = ask2;
        this.askvol2 = askvol2;
        this.ask3 = ask3;
        this.askvol3 = askvol3;
        this.ask4 = ask4;
        this.askvol4 = askvol4;
        this.ask5 = ask5;
        this.askvol5 = askvol5;

        this.lastTradeDate = update;

        this.lastNotifyTime = 0;
    }

    public String getCode() {
        return this.code;
    }

    public int getMarketId() {
        return this.market_id;
    }

    public String getMarketCode() {
        return this.m_code;
    }
    
    public void setMarketId(int market_id) {
        this.market_id = market_id;
    }
    
    public void setMarketCode(String market_code) {
        this.m_code = market_code;
    }

    public String getName() {
        return this.name;
    }

    public Float getPrice() {
        return this.price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Float getOpen() {
        return this.open;
    }

    public void setOpen(Float open) {
        this.open = open;
    }

    public Float getLow() {
        return this.Low;
    }

    public void setLow(Float Low) {
        this.Low = Low;
    }

    public Float getHigh() {
        return this.High;
    }

    public void setHigh(Float High) {
        this.High = High;
    }

    public Float getChangePercentage() {
        return this.changePercentage;
    }

    public void setChangePercentage(Float changePercentage) {
        this.changePercentage = changePercentage;
    }

    public Float getVolume() {
        return this.volume;
    }

    public Float getBid1() {
        return this.bid1;
    }

    public Float getBidVol1() {
        return this.bidvol1;
    }

    public Float getBid2() {
        return this.bid2;
    }

    public Float getBidVol2() {
        return this.bidvol2;
    }

    public Float getBid3() {
        return this.bid3;
    }

    public Float getBidVol3() {
        return this.bidvol3;
    }

    public Float getBid4() {
        return this.bid4;
    }

    public Float getBidVol4() {
        return this.bidvol4;
    }

    public Float getBid5() {
        return this.bid5;
    }

    public Float getBidVol5() {
        return this.bidvol5;
    }

    public Float getAsk1() {
        return this.ask1;
    }

    public Float getAskVol1() {
        return this.askvol1;
    }

    public Float getAsk2() {
        return this.ask2;
    }

    public Float getAskVol2() {
        return this.askvol2;
    }

    public Float getAsk3() {
        return this.ask3;
    }

    public Float getAskVol3() {
        return this.askvol3;
    }

    public Float getAsk4() {
        return this.ask4;
    }

    public Float getAskVol4() {
        return this.askvol4;
    }

    public Float getAsk5() {
        return this.ask5;
    }

    public Float getAskVol5() {
        return this.askvol5;
    }

    public void setVolume(Float volume) {
        this.volume = volume;

        if (volume != null && volume == 0) {
            this.volume = null;
        }
    }

    public String getLastTradeDate() {
        return this.lastTradeDate == null || this.lastTradeDate.equals("")
                || this.lastTradeDate.equals("null") ? "-" : this.lastTradeDate;
    }

    public String getStringPrice() {
        return toStringValue(this.price, "-");
    }

    public String getStringOpen() {
        return toStringValue(this.open, "-");
    }

    public String getStringHigh() {
        return toStringValue(this.High, "-");
    }

    public String getStringLow() {
        return toStringValue(this.Low, "-");
    }

    public String getStringAsk1() {
        return toStringValue(this.ask1, "-");
    }

    public String getStringAsk2() {
        return toStringValue(this.ask2, "-");
    }

    public String getStringAsk3() {
        return toStringValue(this.ask3, "-");
    }

    public String getStringAsk4() {
        return toStringValue(this.ask4, "-");
    }

    public String getStringAsk5() {
        return toStringValue(this.ask5, "-");
    }

    public String getStringAskVol1() {
        return toStringHand(this.askvol1, "-");
    }

    public String getStringAskVol2() {
        return toStringHand(this.askvol2, "-");
    }

    public String getStringAskVol3() {
        return toStringHand(this.askvol3, "-");
    }

    public String getStringAskVol4() {
        return toStringHand(this.askvol4, "-");
    }

    public String getStringAskVol5() {
        return toStringHand(this.askvol5, "-");
    }

    public String getStringBid1() {
        return toStringValue(this.bid1, "-");
    }

    public String getStringBid2() {
        return toStringValue(this.bid2, "-");
    }

    public String getStringBid3() {
        return toStringValue(this.bid3, "-");
    }

    public String getStringBid4() {
        return toStringValue(this.bid4, "-");
    }

    public String getStringBid5() {
        return toStringValue(this.bid1, "-");
    }

    public String getStringBidVol1() {
        return toStringHand(this.bidvol1, "-");
    }

    public String getStringBidVol2() {
        return toStringHand(this.bidvol2, "-");
    }

    public String getStringBidVol3() {
        return toStringHand(this.bidvol3, "-");
    }

    public String getStringBidVol4() {
        return toStringHand(this.bidvol4, "-");
    }

    public String getStringBidVol5() {
        return toStringHand(this.bidvol5, "-");
    }

    public String getStringChangeAndChangePercentage() {
        String value1 = this.change == null ? "-" : new DecimalFormat(
                "+0.00;-0.00").format(this.change);

        String value2 = getStringChangePercentage();

        if (!value1.equals("-") && value2.equals("-")) {
            return value1;
        }

        if (value1.equals("-") && !value2.equals("-")) {
            return value2;
        }

        return value1.equals("-") && value2.equals("-") ? "-" : value1 + " ("
                + value2 + ")";
    }

    public String getStringChangePercentage() {
        String value = this.changePercentage == null ? "-" : new DecimalFormat(
                "+0.00;-0.00").format((this.changePercentage * 100.0f));

        if (!value.equals("-")) {
            value += "%";
        }

        return value;
    }

    public String getStringDaysPerformance() {
        String open = this.open == null ? "-" : Extensions.format(this.open);
        String low = this.Low == null ? "-" : Extensions.format(this.Low);
        String high = this.High == null ? "-" : Extensions.format(this.High);

        return "o" + open + ",h" + high + ",l" + low;
    }

    public String getStringVolumeAndAverageVolume() {
        String value1 = this.volume == null || this.volume == 0 ? "-"
                : Extensions.fromVolumeToShortHand(this.volume);

        String value2 = "-";

        if (value1.equals("-") && value2.equals("-")) {
            return "-";
        }

        if (value1.equals("-")) {
            return value2;
        }

        if (value2.equals("-")) {
            return value1;
        }

        return value1 + " / " + value2;
    }

    public String getStringVolume() {
        String value = this.volume == null || this.volume == 0 ? "-"
                : Extensions.fromVolumeToShortHand(this.volume);
        return value;
    }

    public String getStringTurnover() {
        String value = this.turnover == null || this.turnover == 0 ? "-"
                : Extensions.fromTurnOverToShort(this.turnover);
        return value;
    }

    public String getStringYesterdayClose() {
        return toStringValue(this.yesterdayClose, "-");
    }

    private String toStringValue(Float value, String nullValue) {
        return value == null ? nullValue : Extensions.format(value);
    }

    private String toStringHand(Float value, String nullValue) {
        return value == null ? nullValue : Extensions.fromValueToAbbreviation(value);
    }

    public boolean isUp() {
        return this.change != null && this.change > 0;
    }

    public boolean isDown() {
        return this.change != null && this.change < 0;
    }

    public boolean isMarketIndex() {
        return this.code.startsWith("^");
    }

    private long getLastNDayOpenTime(int lastNDay) {
        Calendar currCal = Calendar.getInstance();
        currCal.setTimeInMillis(System.currentTimeMillis()
                - (lastNDay * Constants.DAY_TO_MILLSECONDS));

        Calendar retCal = Calendar.getInstance();
        retCal.clear();
        retCal.set(currCal.get(Calendar.YEAR), currCal.get(Calendar.MONTH),
                currCal.get(Calendar.DAY_OF_MONTH), 9, 0, 0);
        return retCal.getTimeInMillis();
    }

    private long getLastNDayCloseTime(int lastNDay) {
        Calendar currCal = Calendar.getInstance();
        currCal.setTimeInMillis(System.currentTimeMillis()
                - (lastNDay * Constants.DAY_TO_MILLSECONDS));

        Calendar retCal = Calendar.getInstance();
        retCal.clear();
        retCal.set(currCal.get(Calendar.YEAR), currCal.get(Calendar.MONTH),
                currCal.get(Calendar.DAY_OF_MONTH), 15, 0, 0);
        return retCal.getTimeInMillis();
    }
 
 

}
